/**
* User: Oleksii Savchenko
* Date: 25.01.13
* Time: 10:34
*/
describe('Made ajax request', function(){
    beforeEach(function(){
        this.xhr = sinon.useFakeXMLHttpRequest();
        var requests = this.requests = [];

        this.xhr.onCreate = function (xhr) {
            requests.push(xhr);
        };

        this.callback = sinon.spy();
    });

    afterEach(function(){
        this.xhr.restore();
        this.callback.reset();
    });

   it('get method should exist', function(){
       expect(ajax.get).toBeDefined();
   });

   it('Should get information from server', function(){
       var options = {
           url: "/someIndex.html",
           data: null
       };
       var params = 'id=34';
       ajax.get(options, this.callback, params);
       expect(this.requests.length).toBe(1);

       this.requests[0].respond(200, { "Content-Type": "application/json" },
           '[{"params": 12, "data": "Hey there"}]');

       expect(this.callback).toHaveBeenCalledWith([{"params": 12, "data": "Hey there"}]);
   });

    it('Create method should exist', function(){
        expect(ajax.create).toBeDefined();
    });

    it('Should create information on Server', function(){
        var options = {
            url: "/someIndex.html",
            data: {
                id: 10,
                title: 'article'
            }
        };

        ajax.create(options, this.callback);
        expect(this.requests.length).toBe(1);

        this.requests[0].respond(200, { "Content-Type": "text/json" }, 'item_1');
        expect(this.callback).toHaveBeenCalledWith('item_1');
    });

    it('Update method should exist', function(){
        expect(ajax.update).toBeDefined();
    });

    it('Should create information on Server', function(){
        var options = {
            url: "/someIndex.html",
            data: {
                id: 1,
                title: 'article'
            }
        };

        ajax.update(options, this.callback);
        expect(this.requests.length).toBe(1);

        this.requests[0].respond(200, { "Content-Type": "text/json" }, 'true');
        expect(this.callback).toBeTruthy();
    });

    it('Remove method should exist', function(){
        expect(ajax.remove).toBeDefined();
    });

    it('Should create information on Server', function(){
        var options = {
            url: "/remove_user",
            data: {
                id: 101
            }
        };

        ajax.remove(options, this.callback);
        expect(this.requests.length).toBe(1);

        this.requests[0].respond(200, { "Content-Type": "text/json" }, 'true');
        expect(this.callback).toBeTruthy();
    });

    describe('Checking query method', function(){

        it('can get header informations', function(){
            var options = {
                url: "/someIndex.html/34",
                data: null
            };
            ajax. _ajaxRequest(options, this.callback, 'POST');
            expect(this.requests.length).toBe(1);
            this.requests[0].respond(200, { "Content-Type": "text/json" }, 'true');

            expect(this.requests[0].async).toBeTruthy();
            expect(this.requests[0].status).toBe(200);
            expect(this.requests[0].statusText).toBe('OK');
            expect(this.requests[0].getResponseHeader('Content-Type')).toBe('text/json');
            expect(this.requests[0].method).toBe('POST');
            expect(this.requests[0].url).toBe('/someIndex.html/34');
        });

        it('must checked for request body', function(){
            var options = {
                url: "/someIndex.html/34",
                data: {
                    name: "testName",
                    id: 14
                }
            };
            ajax. _ajaxRequest(options, this.callback, 'PUT');
            expect(this.requests.length).toBe(1);

            this.requests[0].respond(200, { "Content-Type": "text/json" }, 'true');
            expect(this.requests[0].requestBody).toBe(JSON.stringify(options.data));
        });

    });

    describe('Checking for xhr object and switching on ActiveX', function(){

        it('checking for XMLHttpRequest', function(){
            var fakeXMLHttpRequest = {};

            window['XMLHttpRequest'] = function(){
                return fakeXMLHttpRequest;
            };
            expect(ajax._wrapXhr(fakeXMLHttpRequest)).toBe(fakeXMLHttpRequest);
        });

        it('checking for ActiveX Msxm12.XMLHTTP.6.0', function(){
            var fakeXHR = undefined;
            var ActiveXObject6 = {};

            window.ActiveXObject = function(msg){
                return ActiveXObject6;
            };
            expect(ajax._wrapXhr(fakeXHR)).toEqual(ActiveXObject6);
        });

        it('checking for ActiveX Msxm12.XMLHTTP.3.0', function(){
            var fakeXHR = undefined;
            var ActiveXObject3 = {};

            window.ActiveXObject = function(msg){
                if(msg == 'Msxm12.XMLHTTP.6.0'){
                    throw new Error('Don\'t found ActiveX Msxm12.XMLHTTP.6.0');
                } else {
                    return ActiveXObject3;
                }
            };
            expect(ajax._wrapXhr(fakeXHR)).toEqual(ActiveXObject3);
        });

        it('checking for exception on XMLHttpRequest not supported', function(){
            var fakeXHR = undefined;

            window.ActiveXObject = function(msg){
                if(msg == 'Msxm12.XMLHTTP.6.0'){
                    throw new Error('Don\'t found ActiveX Msxm12.XMLHTTP.6.0');
                } else if(msg == 'Msxm12.XMLHTTP.3.0') {
                    throw new Error('Don\'t found ActiveX Msxm12.XMLHTTP.3.0');
                }
            };
            expect(function(){ajax._wrapXhr(fakeXHR)}).toThrow('XMLHttpRequest not supported');
        });

    });

});
